package com.example.luckysystem.service.activitystatus.impl;

import com.example.luckysystem.common.errorcode.ServiceErrorCodeConstants;
import com.example.luckysystem.common.exception.ServiceException;
import com.example.luckysystem.controller.param.DrawPrizeParam;
import com.example.luckysystem.dao.dataobject.*;
import com.example.luckysystem.service.ActivityService;
import com.example.luckysystem.service.activitystatus.ActivityStatusManager;
import com.example.luckysystem.service.activitystatus.operater.AbstractActivityOperator;
import com.example.luckysystem.service.dto.ConvertActivityStatusDTO;
import com.example.luckysystem.service.enums.ActivityStatusEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @version 1.0
 * @Author shangjialu
 * @Date 2024/12/15 18:54
 * @注释
 */
@Component
public class ActivityStatusManagerImpl implements ActivityStatusManager {

    private static final Logger logger = LoggerFactory.getLogger(ActivityStatusManagerImpl.class);

    @Autowired
    private final Map<String, AbstractActivityOperator> operatorMap = new HashMap<>();
    //key：名称   :value:具体的对象
    @Autowired
    private ActivityService activityService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void handlerEvent(ConvertActivityStatusDTO convertActivityStatusDTO) {
        //在这里加入设计模式
        // 1、活动状态扭转有依赖性，导致代码维护性差
        //先处理人员奖品，后处理活动，最后处理更新缓存，即实现责任链模式
        //map<string,abstractAcyivityOperator> string(key)是活动，奖品，人员类
        //abstractAcyivityOperator，指的是三个类相对应的扭转状态的操作类xxxoperate
        //策略模式是抽象类的实现，责任链模式是根据方法传入的1,2
        // 和各自operator的sequence中的1,2 进行比较，先执行1，后执行2
        // 2、状态扭转条件可能会扩展，当前写法，扩展性差，维护性差

        if (CollectionUtils.isEmpty(operatorMap)) {
            //说明operator实现类没有实现
            logger.warn("ActivityStatusManagerImpl operatorMap 为空！");
            return;
        }
        Map<String, AbstractActivityOperator> currMap = new HashMap<>(operatorMap);
        Boolean update = false;
        // 先处理：人员、奖品
        update = processConvertStatus(convertActivityStatusDTO, currMap, 1);
        // 后处理：活动
        update = processConvertStatus(convertActivityStatusDTO, currMap, 2) || update;
        // 更新缓存
        if (update) {
            activityService.cacheActivity(convertActivityStatusDTO.getActivityId());
        }

    }

    @Override
    public void rollbackHandlerEvent(ConvertActivityStatusDTO convertActivityStatusDTO) {
        // operatorMap：活动、奖品、人员
        // 活动是否需要回滚？？ 绝对需要，
        // 原因：奖品都恢复成INIT，那么这个活动下的奖品绝对没抽完
        for (AbstractActivityOperator operator : operatorMap.values()) {
            operator.convert(convertActivityStatusDTO);
        }

        // 缓存更新
        activityService.cacheActivity(convertActivityStatusDTO.getActivityId());
    }

    /**
     * 扭转状态currMap里面对应operator的状态
     * @param convertActivityStatusDTO
     * @param currMap
     * @param sequence
     * @return
     */
    private Boolean processConvertStatus(ConvertActivityStatusDTO convertActivityStatusDTO,
                                         Map<String, AbstractActivityOperator> currMap,
                                         int sequence) {
        Boolean update = false;
        // 遍历currMap
        Iterator<Map.Entry<String, AbstractActivityOperator>> iterator =
                currMap.entrySet().iterator();
        while (iterator.hasNext()) {
            AbstractActivityOperator operator = iterator.next().getValue();
            // Operator 是否需要转换
            if (operator.sequence() != sequence
                    || !operator.needConvert(convertActivityStatusDTO)) {
                continue;
            }
            // 需要转换：转换
            if (!operator.convert(convertActivityStatusDTO)) {
                logger.error("{}状态转换失败！", operator.getClass().getName());
                //iterator key是operator.getClass().getName()
                throw new ServiceException(ServiceErrorCodeConstants.ACTIVITY_STATUS_CONVERT_ERROR);
            }
            // currMap 删除当前 Operator
            //某一个operate操作执行完了，即某一个类的状态转换完了，就直接删除这个类的状态转换操作
            iterator.remove();
            update = true;
        }

        // 返回
        return update;
    }


}
